﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Linq;
using System.Web.Mvc;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;
using System.Web.Security;
using System.Web.Profile;
using System.Configuration;
using ESN.Models;
using ESN.Helpers;


namespace ESN.Controllers
{
    public class ConnectController : Controller
    {
        private ESNCoreDbContext core = new ESNCoreDbContext();

        //private string ClientID = "000000004008C210";
        //private string ClientSecret = "QMTx1-bcCYCyZPQeB7bKTg1kfPYbV7Bh";
        //private string ClientUrl = "http://test.thi.vn:1636";
        private string ClientID = ConfigurationManager.AppSettings["ClientID"];
        private string ClientSecret = ConfigurationManager.AppSettings["ClientSecret"];
        private string ClientUrl = ConfigurationManager.AppSettings["ClientUrl"];
        public ActionResult Index()
        {
            return View("Error");
        }

        public ActionResult LogIn()
        {
            var logInUrl = ClientUrl + "%2FConnect%2FLogIn";
            if (Request.QueryString["code"] == null)
            {
                if (Request.QueryString["error_description"] != null)
                    ViewBag.ErrorMessage = Request.QueryString["error_description"];

                return View();
            }
            //string postData = "client_id=" + ClientID + "&redirect_uri=http%3A%2F%2Ftest.thi.vn%3A1636%2FLive%2FLogIn&client_secret=" + ClienSecret + "&code=" + Request.QueryString["code"] + "&grant_type=authorization_code";
            Dictionary<string, string> postData = new Dictionary<string,string>();
            postData.Add("client_id", ClientID);
            postData.Add("redirect_uri", logInUrl);
            postData.Add("client_secret", ClientSecret);
            postData.Add("code", Request.QueryString["code"]);
            postData.Add("grant_type", "authorization_code");
            string liveToken;
            try
            {
                liveToken = RemoteHelper.Post("https://oauth.live.com/token", postData);
            }
            catch
            {
                ViewBag.ErrorMessage = "Cannot get Access token code";
                return View();
            }


            var parser = new JavaScriptSerializer();
            LiveOAuthResponse liveResponse = parser.Deserialize<LiveOAuthResponse>(liveToken);

            //get user info
            string liveInfo;
            LiveUserInfo userInfo = new LiveUserInfo();
            try
            {
                liveInfo = RemoteHelper.Get("https://apis.live.net/v5.0/me?access_token=" + liveResponse.access_token);
                userInfo = parser.Deserialize<LiveUserInfo>(liveInfo);
                ViewBag.Response = liveInfo;
            }
            catch
            {
                ViewBag.ErrorMessage = "Can not get User Info";
            }
            if (Membership.GetUser("live" + userInfo.id) == null)
            {
                var newUser = Membership.CreateUser("live" + userInfo.id, Membership.GeneratePassword(9, 1), userInfo.emails.account);
                var newUserProfile = new CustomProfile();
                newUserProfile.UserId = (Guid) newUser.ProviderUserKey;
                if (userInfo.name == null)
                {
                    newUserProfile.DisplayName = newUser.UserName;
                }
                else
                {
                    newUserProfile.DisplayName = userInfo.name;
                }
                newUserProfile.FirstName = userInfo.first_name;
                newUserProfile.LastName = userInfo.last_name;
                if (userInfo.gender == "female")
                {
                    newUserProfile.Gender = true;
                    newUserProfile.Avatar = "/Content/images/girl.png";
                }
                else
                {
                    newUserProfile.Gender = false;
                    newUserProfile.Avatar = "/Content/images/boy.png";
                }
                
                //important
                newUserProfile.UserName = "live" + userInfo.id;

                core.Profiles.Add(newUserProfile);
                core.SaveChanges();
            }
            FormsAuthentication.SetAuthCookie("live" + userInfo.id, false);
            return RedirectToAction("Index", "Home");
        }
        [Authorize(Roles="Admin")]
        public string GetToken()
        {
            var logInUrl = ClientUrl + "%2FConnect%2FGetToken";

            if (Request.QueryString["code"] == null)
            {
                if (Request.QueryString["error_description"] != null)
                    return Request.QueryString["error_description"];
                else
                    return "<a href=\"https://oauth.live.com/authorize?client_id=" + ClientID + "&scope=wl.offline_access%20wl.signin%20wl.basic%20wl.skydrive_update%20wl.emails&response_type=code&redirect_uri=" + logInUrl + "\">Get token</a>";
            }
            //string postData = "client_id=" + ClientID + "&redirect_uri=http%3A%2F%2Ftest.thi.vn%3A1636%2FLive%2FLogIn&client_secret=" + ClienSecret + "&code=" + Request.QueryString["code"] + "&grant_type=authorization_code";
            Dictionary<string, string> postData = new Dictionary<string, string>();
            postData.Add("client_id", ClientID);
            postData.Add("redirect_uri", logInUrl);
            postData.Add("client_secret", ClientSecret);
            postData.Add("code", Request.QueryString["code"]);
            postData.Add("grant_type", "authorization_code");
            string liveToken;
            try
            {
                liveToken = RemoteHelper.Post("https://oauth.live.com/token", postData);
            }
            catch
            {
                return "Cannot get Access token code";
            }


            var parser = new JavaScriptSerializer();
            LiveOAuthResponse liveResponse = parser.Deserialize<LiveOAuthResponse>(liveToken);
            var apptk = core.AppToken.Find(1);
            if (apptk == null)
                core.AppToken.Add(liveResponse);
            else
            {
                apptk.access_token = liveResponse.access_token;
                apptk.expires_in = liveResponse.expires_in;
                apptk.refresh_token = liveResponse.refresh_token;
                apptk.scope = liveResponse.scope;
                apptk.token_type = liveResponse.token_type;
            }

            core.SaveChanges();
            return "<a href=\"" + ClientUrl + "/Connect/F5Token\">F5 Token</a>";
        }

        public string F5Token()
        {
            var logInUrl = ClientUrl + "%2FConnect%2FF5Token";
            Dictionary<string, string> postData = new Dictionary<string, string>();
            postData.Add("client_id", ClientID);
            postData.Add("redirect_uri", logInUrl);
            postData.Add("client_secret", ClientSecret);
            postData.Add("refresh_token", core.AppToken.Find(1).refresh_token);
            postData.Add("grant_type", "refresh_token");
            string liveToken;
            try
            {
                liveToken = RemoteHelper.Post("https://oauth.live.com/token", postData);
            }
            catch
            {
                return "Cannot get Access token code";
            }


            var parser = new JavaScriptSerializer();
            LiveOAuthResponse liveResponse = parser.Deserialize<LiveOAuthResponse>(liveToken);
            var apptk = core.AppToken.Find(1);
            if (apptk == null)
                core.AppToken.Add(liveResponse);
            else
            {
                apptk.access_token = liveResponse.access_token;
                apptk.expires_in = liveResponse.expires_in;
                apptk.refresh_token = liveResponse.refresh_token;
                apptk.scope = liveResponse.scope;
                apptk.token_type = liveResponse.token_type;
            }
            return "<a href=\"" + logInUrl + "\">F5 Token</a>";
        }

        [HttpPost]
        [Authorize]
        public bool SendNotice(string[] name, string content)
        {
            Guid online = new Guid();
            if(!PermissionHelper.IsAuthenticated(ref online))
                return false;

            foreach (string item in name)
            {
                int id;
                bool isGroupId = int.TryParse(item, out id);

                if (isGroupId)
                {
                    var group = core.Groups.Find(id);
                    UserNotice n1 = new UserNotice();
                    n1.SenderId = online;
                    n1.NAbout = online.ToString();
                    n1.NContent = HttpUtility.HtmlAttributeEncode(content);
                    n1.NNew = true;
                    n1.UserId = group.OwnerId;
                    core.UserNotices.Add(n1);

                    foreach (var user in group.Members)
                    {
                        UserNotice n2 = new UserNotice();
                        n2.SenderId = online;
                        n2.NAbout = online.ToString();
                        n2.NContent = HttpUtility.HtmlAttributeEncode(content);
                        n2.NNew = true;
                        n2.UserId = user.UserId;
                        core.UserNotices.Add(n2);
                    }
                }
                else
                {
                    var user = core.Profiles.Where(u => u.UserName == item);
                    if (user.Count() > 0)
                    {
                        UserNotice n3 = new UserNotice();
                        n3.SenderId = online;
                        n3.NAbout = online.ToString();
                        n3.NContent = HttpUtility.HtmlAttributeEncode(content);
                        n3.NNew = true;
                        n3.UserId = user.First().UserId;
                        core.UserNotices.Add(n3);
                    }
                }

            }
            core.SaveChanges();
            return true;
        }
    }
}
